import {
  Observable, of,
  tap,
} from 'rxjs'

// 里面包含路由处理函数
const next = {
  handle() {
    console.log(`pay...`)
    return of('路由处理函数的返回值') // 路由处理函数返回一个可观察对象
  }
}

export class Logger1Interceptor {
  intercept(_, next): Observable<any> {
    console.log('Before1')
    const now = Date.now()
    return next.handle().pipe(
      tap({
        next: val => console.log(`After1... ${Date.now() - now}ms`, val)
      }),
    )
  }
}
export class Logger2Interceptor {
  intercept(_, next): Observable<any> {
    console.log('Before2')
    const now = Date.now()
    return next.handle().pipe(
      tap({
        next: val => console.log(`After2... ${Date.now() - now}ms`, val)
      }),
    )
  }
}

const logging1Interceptor = new Logger1Interceptor()
const logging2Interceptor = new Logger2Interceptor()

/**
 * 执行数组中的每一个拦截器
 * @param interceptors 拦截器组成的数组 
 */
function executeInterceptors(interceptors) {
  // currentHandler 里面包含路由处理函数执行逻辑
  let currentHandler = () => next.handle()
  interceptors.forEach(interceptor => {
    const previousHandler = currentHandler
    currentHandler = () => interceptor.intercept(null, { handle: previousHandler })
  })

  return currentHandler()
}

executeInterceptors([logging1Interceptor, logging2Interceptor])
  .subscribe(console.log);

/**
 * 定义拦截器实例
 * 1. 使用 Logger1Interceptor 创建一个 logging1Interceptor 拦截器实例
 * 2. 使用 Logger2Interceptor 创建一个 logging2Interceptor 拦截器实例
 * 
 * 定义 executeInterceptors 函数 接收一个数组 其中数组里面的每一个拦截器实例都会执行
 * 3. 执行 executeInterceptors 函数 传入拦截器实例数组 ( 此时执行所有的前置拦截器逻辑 + 路由处理函数逻辑 )
 *   3.1 定义一个 currentHandler 变量 值是一个箭头函数包含路由处理函数的执行  () => next.handle() 
 *     3.1.1 路由处理函数会返回一个可观察对象
 *   3.2 遍历拦截器数组 依次获取每一个拦截器实例
 *     3.2.1 logging1Interceptor 拦截器情况
 *       3.2.1.1 定义一个 previousHandler 变量 值是 () => next.handle()
 *       3.2.1.2 重写 currentHandler 变量 值是 () => Logger1Interceptor.intercept(null, { handle: previousHandler })
 *     3.2.2 logging2Interceptor 拦截器情况
 *       3.2.2.1 定义一个 previousHandler 变量 值是 () => Logger1Interceptor.intercept(null, { handle: previousHandler })
 *       3.2.2.2 重写 currentHandler 变量 值是 () => Logger2Interceptor.intercept(null, { handle: previousHandler })
 *   3.3 执行 currentHandler 函数 并对返回值调用 subscribe 函数
 *     3.3.1 执行 Logger2Interceptor.intercept 函数 ( 前置拦截器逻辑 )
 *       3.3.1.1 执行 Logger1Interceptor.intercept 函数 ( 前置拦截器逻辑 )
 *         3.3.1.1.1 执行 next.handle 函数 ( 路由处理函数 ) 返回一个可观察对象
 *       3.3.1.2 调用可观察对象的 pipe 方法执行 tap 管道操作符 对可观察对象生产发送的值进行副作用处理 ( 后置拦截器逻辑 )
 *     3.3.2 调用可观察对象的 pipe 方法执行 tap 管道操作符 对可观察对象生产发送的值进行副作用处理 ( 后置拦截器逻辑 )
 */

